package com.lhl.task;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.quartz.Job;
import org.quartz.JobExecutionContext;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 所有添加的定时任务都应该继承该Job
 * @author Liu Hanlin
 * @create 2024-11-05 23:21
 */
public abstract class BaseJob<T extends BaseJob.BaseParams> implements Job {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private Class<T> paramType;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        // TODO: 添加记录日志

        Object object = jobExecutionContext.getMergedJobDataMap().get("params");
        if(! (object instanceof String) ){
            // TODO: 自定义异常
           throw new RuntimeException("参数类型错误");
        }
        try {
            // 获取参数对象
            T baseParams = objectMapper.readValue((String) object, getParamType());
            // 通过JobExecutionContext获取数据库中存储的参数
            this.execute(jobExecutionContext, baseParams);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public abstract void execute(JobExecutionContext jobExecutionContext, T params);

    /**
     * 通过反射获取参数类型的Class对象
     * @return 参数类型的Class对象
     */
    @SuppressWarnings("unchecked")
    protected Class<T> getParamType() {
        Type genericSuperclass = getClass().getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length > 0 && actualTypeArguments[0] instanceof Class) {
                return (Class<T>) actualTypeArguments[0];
            }
        }
        throw new IllegalStateException("无法获取参数类型");
    }

    /**
     * 任务参数
     */
    protected static class BaseParams{

    }
}
